package com.roncoo.education.course.service.admin.biz;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.roncoo.education.common.core.base.Page;
import com.roncoo.education.common.core.base.PageUtil;
import com.roncoo.education.common.core.base.Result;
import com.roncoo.education.common.core.enums.StatusIdEnum;
import com.roncoo.education.common.core.tools.BeanUtil;
import com.roncoo.education.common.core.tools.DateUtil;
import com.roncoo.education.common.elasticsearch.EsExperiment;
import com.roncoo.education.common.service.BaseBiz;
import com.roncoo.education.course.dao.ExperimentDao;
import com.roncoo.education.course.dao.impl.mapper.entity.Experiment;
import com.roncoo.education.course.dao.impl.mapper.entity.ExperimentExample;
import com.roncoo.education.course.dao.impl.mapper.entity.ExperimentExample.Criteria;
import com.roncoo.education.course.dao.impl.mapper.entity.ExperimentWithBLOBs;
import com.roncoo.education.course.service.admin.req.AdminExperimentEditReq;
import com.roncoo.education.course.service.admin.req.AdminExperimentPageReq;
import com.roncoo.education.course.service.admin.req.AdminExperimentSaveReq;
import com.roncoo.education.course.service.admin.resp.AdminExperimentPageResp;
import com.roncoo.education.course.service.admin.resp.AdminExperimentViewResp;
import com.roncoo.education.course.service.api.biz.ApiOptionsBiz;
import com.roncoo.education.system.feign.interfaces.IFeignRoleUser;
import com.roncoo.education.user.feign.interfaces.IFeignLecturer;
import com.roncoo.education.user.feign.interfaces.vo.LecturerViewVO;

import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;

/**
 * ADMIN-实验信息
 *
 * @author wujing
 */
@Component
@RequiredArgsConstructor
public class AdminExperimentBiz extends BaseBiz {

    @NotNull
    private final ExperimentDao dao;
    @Autowired
    private ApiOptionsBiz optionsBiz;
    @NotNull
    private final IFeignLecturer feignLecturer;
    @NotNull
    private final IFeignRoleUser feignRoleUser;
    
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 实验信息分页
     *
     * @param req 实验信息分页查询参数
     * @return 实验信息分页查询结果
     */
    public Result<Page<AdminExperimentPageResp>> page(AdminExperimentPageReq req, Long userId) {    	
        ExperimentExample example = new ExperimentExample();
        Criteria c = example.createCriteria();
        if (StringUtils.hasText(req.getMingcheng())) {
            c.andMingchengLike(PageUtil.rightLike(req.getMingcheng()));
        }
        // 仅仅只有资源管理员角色，只能看到自己的资源
        if (feignRoleUser.isOnlyResourceManager(userId)) {
        	c.andUserIdEqualTo(userId);
        }
        example.setOrderByClause("experiment_sort asc, id desc");
        Page<Experiment> page = dao.page(req.getPageCurrent(), req.getPageSize(), example);        
        page.setList(optionsBiz.setOptionNameByOptionValue(page.getList()));
        Page<AdminExperimentPageResp> respPage = PageUtil.transform(page, AdminExperimentPageResp.class);
        if (CollUtil.isNotEmpty(respPage.getList())) {
            List<Long> lecturerIdList = respPage.getList().stream().map(AdminExperimentPageResp::getZuozheId).collect(Collectors.toList());
            Map<Long, String> lecturerNameMap = feignLecturer.listByIds(lecturerIdList);

            for (AdminExperimentPageResp resp : respPage.getList()) {
                resp.setZuozheName(lecturerNameMap.get(resp.getZuozheId()));
            }
        }
        return Result.success(respPage);
    }    
//    public Result<Page<AdminExperimentPageResp>> page2(AdminExperimentPageReq req) {
//        ExperimentExample example = new ExperimentExample();
//        Criteria c = example.createCriteria();
//        Page<Experiment> page = dao.page(req.getPageCurrent(), req.getPageSize(), example);
//        Page<AdminExperimentPageResp> respPage = PageUtil.transform(page, AdminExperimentPageResp.class);
//        return Result.success(respPage);
//    }

    /**
     * 实验信息添加
     *
     * @param req 实验信息
     * @return 添加结果
     */
    public Result<String> save(AdminExperimentSaveReq req, Long userId) {
    	ExperimentWithBLOBs record = BeanUtil.copyProperties(req, ExperimentWithBLOBs.class);
    	record.setUserId(userId);
        if (dao.save(record) > 0) {
            EsExperiment esExperiment = BeanUtil.copyProperties(record, EsExperiment.class);
            elasticsearchRestTemplate.index(new IndexQueryBuilder().withObject(esExperiment).build(), IndexCoordinates.of(EsExperiment.EXPERIMENT));        	
            return Result.success("操作成功");
        }
        return Result.error("操作失败");
    }

    /**
     * 实验信息查看
     *
     * @param id 主键ID
     * @return 实验信息
     */
    public Result<AdminExperimentViewResp> view(Long id) {
        return Result.success(BeanUtil.copyProperties(dao.getById(id), AdminExperimentViewResp.class));
    }

    /**
     * 实验信息修改
     *
     * @param req 实验信息修改对象
     * @return 修改结果
     */
    public Result<String> edit(AdminExperimentEditReq req) {
    	ExperimentWithBLOBs record = BeanUtil.copyProperties(req, ExperimentWithBLOBs.class);
        if (dao.updateById(record) > 0) {
            EsExperiment esExperiment = BeanUtil.copyProperties(record, EsExperiment.class);
            elasticsearchRestTemplate.index(new IndexQueryBuilder().withObject(esExperiment).build(), IndexCoordinates.of(EsExperiment.EXPERIMENT));
            return Result.success("操作成功");
        }
        return Result.error("操作失败");
    }

    /**
     * 实验信息删除
     *
     * @param id ID主键
     * @return 删除结果
     */
    public Result<String> delete(Long id) {
        if (dao.deleteById(id) > 0) {
        	elasticsearchRestTemplate.delete(id.toString(), EsExperiment.class);
            return Result.success("操作成功");
        }
        return Result.error("操作失败");
    }
    
    public void syncEs() {
        // 获取全部实验
        ExperimentExample example = new ExperimentExample();
        example.createCriteria().andStatusIdEqualTo(StatusIdEnum.YES.getCode());
        List<Experiment> list = dao.listByExample(example);
        list = optionsBiz.setOptionNameByOptionValue(list);
        
        List<Long> lecturerIdList = list.stream().map(Experiment::getZuozheId).collect(Collectors.toList());
        Map<Long, LecturerViewVO> lecturerNameMap = feignLecturer.listByIds2(lecturerIdList);
        
        if (CollUtil.isNotEmpty(list)) {
            List<IndexQuery> queries = new ArrayList<>();
            for (Experiment experiment : list) {
                EsExperiment esExperiment = BeanUtil.copyProperties(experiment, EsExperiment.class);
                esExperiment.setGmtCreate(DateUtil.fromLocalDateTime(experiment.getGmtCreate()));
                esExperiment.setGmtModified(DateUtil.fromLocalDateTime(experiment.getGmtModified()));
                
                LecturerViewVO lecturer = lecturerNameMap.get(experiment.getZuozheId());
    			if (lecturer != null) {            				
    				esExperiment.setLecturerName(lecturer.getLecturerName());
    				esExperiment.setLecturerSchool(lecturer.getLecturerSchool());
    			}	
                
                queries.add(new IndexQueryBuilder().withObject(esExperiment).build());
            }
            // 更新es
            elasticsearchRestTemplate.indexOps(EsExperiment.class).delete();
            elasticsearchRestTemplate.bulkIndex(queries, IndexCoordinates.of(EsExperiment.EXPERIMENT));
        }      
    }   
}
